import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.Event;
import flash.display.Sprite;
import flash.net.NetConnection;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import fl.data.DataProvider;
import fl.controls.dataGridClasses.DataGridColumn;
using Main;
class Main extends flash.display.Sprite
{
	static var app:String='/admin';
	static var path:String;
	var nc:NetConnection;
	var applications:fl.controls.List;
	var logOutput : fl.controls.TextArea;
	var dataGrid : fl.controls.DataGrid;
	var input : fl.controls.TextInput;
	var btn : fl.controls.Button;
	var view : Sprite;
	public static function main()
	{
		flash.Lib.current.addChild(new Main());
		
	}
	public function new()
	{
		super();
		addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		view = createView();
		addChild(view);
		nc = new NetConnection();
		nc.client=this;
		nc.objectEncoding = 0;
		nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
		nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onError);
		
	}
	function updateApplications()
	{
		nc.call("getApplications", new flash.net.Responder(onResultGetApplications, onErrorGetApplications));
	}
	function onAddedToStage(event:Event):Void
	{
		removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		stage.scaleMode=StageScaleMode.NO_SCALE;
		stage.align=StageAlign.TOP_LEFT;
		stage.addEventListener(Event.RESIZE, onStageResize); 
		onStageResize(null);
		var uri = getUri();
		log("connecting to rtmp://" + uri);
		path = "rtmp://"+uri;
		nc.connect(path);
	}
	function onError(event:AsyncErrorEvent):Void
	{
		log("onError currentTarget="+event.currentTarget);
		log("text:"+event.text);
		log("error:"+event.error);
	}
	function onStatus(event:NetStatusEvent):Void
	{
		log("onNetStatus code="+event.info.code+", description=" + event.info.description);
		if(event.info.code =='NetConnection.Connect.Success')
		{
			updateApplications();
		}
	}
	function onResultGetApplications(data)
	{
		
		log(data);
		var index = applications.selectedItem==null? -1 : getIndexFromAppName(applications.selectedItem.name);
		applications.dataProvider = new DataProvider(data);
		applications.labelField="name";
		if(index==-1)
		{
			dataGrid.dataProvider = new DataProvider([]);
		}
		else
		{
			applications.selectedIndex = index;
			dataGrid.dataProvider = new DataProvider([applications.getItemAt(index)]);
		}
	}
	/*
	function onResultGetApplications(data)
	{
		log(data);
		var index = applications.selectedItem==null? -1 : getIndexFromAppName(applications.selectedItem.name);
		applications.dataProvider = new DataProvider(data);
		applications.labelField="name";
		if(index==-1)
		{
			dataGrid.dataProvider = new DataProvider([]);
		}
		else
		{
			applications.selectedIndex = index;
			dataGrid.dataProvider = new DataProvider([applications.getItemAt(index)]);
		}
	}
	*/
	function onErrorGetApplications(obj)
	{
		log("Error:"+obj.toString());
		log("text:"+obj.text);
		log("error:"+obj.error);
	}
	function onApplicationChange(event)
	{
		log(event);
		log("app info: name:"+applications.selectedItem.name+", version:"+applications.selectedItem.version);
		input.text = applications.selectedItem.name;
		//dataGrid.dataProvider = new DataProvider([applications.selectedItem]);
		updateApplications();
	}
	function onSendBtn(event:flash.events.MouseEvent):Void
	{
		nc.call("reloadApplication", null, input.text);
		input.text="";
	}
	function onStageResize(event:Event=null):Void
	{
		if(view!=null && view.parent!=null)
		{
			positionMiddle(view);
			if(view.x <0)
				view.x=0;
			if(view.y <0)
				view.y=0;
		}
	}
	function onAppReload() 
	{
		log("onAppReload.");
		updateApplications();
	}
	function onAppStart(arg) 
	{
		log("onAppStart:"+arg);
		updateApplications();
	}
	function onSocketConnect(arg) log("onSocketConnect:"+arg)
	function onClientConnect(arg) log("onClientConnect:"+arg)
	function onClientConnected(arg) 
	{
		log("onClientConnected:"+arg);
	}
	function onClientDisconnected(arg) log("onClientDisconnected:"+arg)
	function onStreamCreate(arg) log("onStreamCreate:"+arg)
	function onStreamDelete(arg) log("onStreamDelete:"+arg)
	function onStreamPublish(arg) log("onStreamPublish:"+arg)
	function onStreamPlay(arg) log("onStreamPlay:"+arg)
	function onStreamClose(arg) log("onStreamClose:"+arg)
	function onStreamSeek(arg) log("onStreamSeek:"+arg)
	function onStreamPause(arg) log("onStreamPause:"+arg)
	function onStreamRawPause(arg) log("onStreamRawPause:"+arg)
	function onStreamAudioReceive(arg) log("onStreamAudioReceive:"+arg)
	function onStreamVideoReceive(arg) log("onStreamVideoReceive:"+arg)
	function onSharedObjectSubscribe(arg) log("onSharedObjectSubscribe:"+arg)
	function onSharedObjectUnSubscribe(arg) log("onStreamPause:"+arg)
	
	//called from the server:
	//admin.send0("onAppReload");
	//admin.send1("onAppStart", app.config);
	//admin.send1("onSocketConnect", socket.peer().host.toString());
	//admin.send1("onClientConnect", {client:client.socket.peer().host.toString(), obj:obj, arg:arg});
	//admin.send1("onClientConnected", client.socket.peer().host.toString());
	//admin.send1("onClientDisconnected", client.id);
	//admin.send1("onStreamCreate", client.id);
	//admin.send1("onStreamDelete", client.id);
	//admin.send1("onStreamPublish", client.id);
	//admin.send1("onStreamPlay", client.id);
	//admin.send1("onStreamClose", client.id);
	//admin.send1("onStreamSeek", client.id);
	//admin.send1("onStreamPause", client.id);
	//admin.send1("onStreamRawPause", client.id);
	//admin.send1("onStreamAudioReceive", client.id);
	//admin.send1("onStreamVideoReceive", client.id);
	//admin.send1("onSharedObjectSubscribe", info);
	//admin.send1("onSharedObjectUnSubscribe", info);
	
	function getIndexFromAppName(name:String):Int
	{
		for(i in 0...applications.dataProvider.length)
			if(applications.dataProvider.getItemAt(i).name == name)
				return i;
		return -1;
	}
	function createView():Sprite
	{
		var holder = new Sprite();
		var textFormat = new flash.text.TextFormat();
		textFormat.align = flash.text.TextFormatAlign.CENTER;
		
		var background = new flash.display.Shape();
		background.graphics.beginFill(0xDDDDFF, 1.0);
		background.graphics.drawRoundRect(0,0,1020, 660, 20, 20);
		holder.addChild(background);

		logOutput = new fl.controls.TextArea();
		logOutput.restrict="";
		logOutput.x = 10;
		logOutput.y = 10;
		logOutput.width=1000;
		logOutput.height=100;
		holder.addChild(logOutput);
		
		applications = new fl.controls.List();
		applications.x = logOutput.x;
		applications.y = 10.under(logOutput);
		applications.width = 200;
		applications.height = 500;
		applications.addEventListener(flash.events.Event.CHANGE, onApplicationChange);
		holder.addChild(applications);

		dataGrid = new fl.controls.DataGrid();
		dataGrid.x = 10.after(applications);
		dataGrid.y = applications.y;
		dataGrid.width = logOutput.width - dataGrid.x + 10;
		dataGrid.height = applications.height;
		var col1 = new DataGridColumn("name");
		var col2 = new DataGridColumn("version");
		var col3 = new DataGridColumn("clients");
		col3.labelFunction = function(obj)
		{
			return obj.clients.length;
		}
		var col4 = new DataGridColumn("streams");
		col4.labelFunction = function(obj)
		{
			return obj.streams.length;
		}
		var col5 = new DataGridColumn("objects");
		col5.labelFunction = function(obj)
		{
			return obj.objects.length;
		}
		dataGrid.columns = [col1,col2,col3,col4,col5];
		holder.addChild(dataGrid);
		
		var label = new fl.controls.Label();
		label.text = "";
		label.setStyle("textFormat",textFormat);
		label.width = applications.width;
		label.x = applications.x;
		label.y = 10.under(applications);
		holder.addChild(label);
		
		btn = new fl.controls.Button();
		btn.label="reload";
		btn.x = dataGrid.x + dataGrid.width - btn.width;
		btn.y= 10.under(dataGrid);
		btn.addEventListener(flash.events.MouseEvent.CLICK, onSendBtn);
		holder.addChild(btn);
			
		input = new fl.controls.TextInput();
		input.x = 10.after(label);
		input.y = 10.under(dataGrid);
		input.width = btn.x - 10 - input.x;
		input.height = btn.height;
		holder.addChild(input);
		return holder;
	}
	public static function above(i:Int, t:Dynamic):Float
	{
		return cast t.y - t.height - i;
	}
	public static function under(i:Int, t:Dynamic):Float
	{
		return cast t.y + t.height + i;
	}
	public static function after(i:Int, t:Dynamic):Float
	{
		return cast t.x + t.width + i;
	}
	public static function before(i:Int, t:Dynamic):Float
	{
		return cast t.x - t.width - i;
	}
	function positionMiddle(obj:flash.display.DisplayObject)
	{
		obj.x = (flash.Lib.current.stage.stageWidth-obj.width)/2;
		obj.y = (flash.Lib.current.stage.stageHeight-obj.height)/2;
	}
	function log(msg:Dynamic)
	{
		logOutput.text+= formatDate(Date.now()) + " " + msg+"\n";
		logOutput.textField.scrollV = logOutput.textField.maxScrollV;
	}
	function formatDate(d:Date):String
	{
		var h:Dynamic = d.getHours();
		if(h<10) h="0"+h;
		var m:Dynamic = d.getMinutes();
		if(m<10) m="0"+m;
		return "[" + h + ":" + m + "]";
	}
	function getUri():String
	{
		var parameters:Dynamic = flash.Lib.current.loaderInfo.parameters;
		//trace(parameters);
		var u = Reflect.field(parameters, "uri");
		if(u!=null)
			return u;
		var h = Reflect.field(parameters, "host");
		var p = Reflect.field(parameters, "port");
		var a = Reflect.field(parameters, "app");
		return (h==null?"localhost":h) + (p==null?":1935":":"+p) + (a==null?app:a);
	}
}
